home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 001-025 / disk_010 / iff / ilbmr.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  6KB  |  166 lines

  1. /*----------------------------------------------------------------------*
  2.  * ILBMR.C  Support routines for reading ILBM files.           11/27/85
  3.  * (IFF is Interchange Format File.)
  4.  *
  5.  * By Jerry Morrison and Steve Shaw, Electronic Arts.
  6.  * This software is in the public domain.
  7.  *
  8.  * This version for the Commodore-Amiga computer.
  9.  *----------------------------------------------------------------------*/
  10.  
  11. #include "packer.h"
  12. #include "ilbm.h"
  13.  
  14. /*--------- FUNCTION DECLARATIONS FOR MANX ------------*/
  15.  
  16. extern IFFP   IFFReadBytes();
  17.  
  18.  
  19. /* ---------- GetCMAP ------------------------------------------------*/
  20. /* pNColorRegs is passed in as a pointer to the number of ColorRegisters
  21.  * caller has space to hold.  GetCMAP sets to the number actually read.*/
  22.  
  23. IFFP GetCMAP(ilbmContext, colorMap, pNColorRegs)
  24. GroupContext *ilbmContext;
  25. WORD *colorMap;
  26. UBYTE *pNColorRegs;
  27. {
  28.    register int nColorRegs;
  29.    register IFFP iffp;
  30.    ColorRegister colorReg;
  31.  
  32.    nColorRegs = ilbmContext->ckHdr.ckSize / sizeofColorRegister;
  33.    if (*pNColorRegs < nColorRegs)
  34.        nColorRegs = *pNColorRegs;
  35.    *pNColorRegs = nColorRegs;   /* Set to the number actually there.*/
  36.  
  37.    for ( ;  nColorRegs > 0;  --nColorRegs)  {
  38.       iffp = IFFReadBytes(ilbmContext, (BYTE *)&colorReg,sizeofColorRegister);
  39.       CheckIFFP();
  40.       *colorMap++ = ( ( colorReg.red   >> 4 ) << 8 ) |
  41.                     ( ( colorReg.green >> 4 ) << 4 ) |
  42.                     ( ( colorReg.blue  >> 4 )      );
  43.    }
  44.    return(IFF_OKAY);
  45. }
  46.  
  47. /*---------- GetBODY ---------------------------------------------------*/
  48. /* NOTE: This implementation could be a LOT faster if it used more of the
  49.  * supplied buffer. It would make far fewer calls to IFFReadBytes (and
  50.  * therefore to DOS Read) and to movemem. */
  51.  
  52. IFFP GetBODY(context, bitmap, mask, bmHdr, buffer, bufsize)
  53. GroupContext *context;
  54. struct BitMap *bitmap;
  55. BYTE *mask;
  56. BitMapHeader *bmHdr;
  57. BYTE *buffer;
  58. LONG bufsize;
  59. {
  60.    register IFFP iffp;
  61.    UBYTE srcPlaneCnt = bmHdr->nPlanes;   /* Haven't counted for mask plane yet*/
  62.    WORD srcRowBytes = RowBytes(bmHdr->w);
  63.    LONG bufRowBytes = MaxPackedSize(srcRowBytes);
  64.    int nRows = bmHdr->h;
  65.    Compression compression = bmHdr->compression;
  66.    register long iPlane, iRow, nEmpty;    /* $$$ int to long */
  67.    register WORD nFilled;
  68.    BYTE *buf, *nullDest, *nullBuf, **pDest;
  69.    BYTE *planes[MaxSrcPlanes]; /* array of ptrs to planes & mask */
  70.  
  71.    if (compression > cmpByteRun1)
  72.       return(CLIENT_ERROR);
  73.  
  74.    /* Complain if client asked for a conversion GetBODY doesn't handle.*/
  75.    if ( srcRowBytes  !=  bitmap->BytesPerRow  ||
  76.                    bufsize < bufRowBytes * 2  ||
  77.                    srcPlaneCnt > MaxSrcPlanes )
  78.       return(CLIENT_ERROR);
  79.  
  80.    if (nRows > bitmap->Rows)
  81.       nRows = bitmap->Rows;
  82.  
  83.    /* Initialize array "planes" with bitmap ptrs; NULL in empty slots.*/
  84.  
  85.    for (iPlane = 0; iPlane < bitmap->Depth; iPlane++)
  86.       planes[iPlane] = (BYTE *)bitmap->Planes[iPlane];
  87.  
  88.    for ( ;  iPlane < MaxSrcPlanes;  iPlane++)
  89.       planes[iPlane] = NL;
  90.  
  91.    /* Copy any mask plane ptr into corresponding "planes" slot.*/
  92.    if (bmHdr->masking == mskHasMask) {
  93.       if (mask != NL)
  94.          planes[srcPlaneCnt] = mask;  /* If there are more srcPlanes than
  95.                * dstPlanes, there will be NULL plane-pointers before this.*/
  96.       else
  97.          planes[srcPlaneCnt] = NL;  /* In case more dstPlanes than src.*/
  98.       srcPlaneCnt += 1;  /* Include mask plane in count.*/
  99.       }
  100.  
  101.    /* Setup a sink for dummy destination of rows from unwanted planes.*/
  102.    nullDest = buffer;
  103.    buffer  += srcRowBytes;
  104.    bufsize -= srcRowBytes;
  105.  
  106.    /* Read the BODY contents into client's bitmap.
  107.     * De-interleave planes and decompress rows.
  108.     * MODIFIES: Last iteration modifies bufsize.*/
  109.  
  110.    buf = buffer + bufsize;  /* Buffer is currently empty.*/
  111.    for (iRow = nRows; iRow > 0; iRow--)  {
  112.       for (iPlane = 0; iPlane < srcPlaneCnt; iPlane++)  {
  113.  
  114.          pDest = &planes[iPlane];
  115.  
  116.          /* Establish a sink for any unwanted plane.*/
  117.          if (*pDest == NL) {
  118.             nullBuf = nullDest;
  119.             pDest   = &nullBuf;
  120.          }
  121.  
  122.          /* Read in at least enough bytes to uncompress next row.*/
  123.          nEmpty  = buf - buffer;          /* size of empty part of buffer.*/
  124.          nFilled = bufsize - nEmpty;      /* this part has data.*/
  125.          if (nFilled < bufRowBytes) {
  126.             /* Need to read more.*/
  127.  
  128.             /* Move the existing data to the front of the buffer.*/
  129.             /* Now covers range buffer[0]..buffer[nFilled-1].*/
  130.             movmem(buf, buffer, nFilled);  /* Could be moving 0 bytes.*/
  131.  
  132.             if (nEmpty > ChunkMoreBytes(context)) {
  133.                /* There aren't enough bytes left to fill the buffer.*/
  134.                nEmpty = ChunkMoreBytes(context);
  135.                bufsize = nFilled + nEmpty;  /* heh-heh */
  136.                }
  137.  
  138.             /* Append new data to the existing data.*/
  139.             iffp = IFFReadBytes(context, &buffer[nFilled], nEmpty);
  140.             CheckIFFP();
  141.  
  142.             buf     = buffer;
  143.             nFilled = bufsize;
  144.             nEmpty  = 0;
  145.          }
  146.  
  147.          /* Copy uncompressed row to destination plane.*/
  148.          if (compression == cmpNone) {
  149.             if (nFilled < srcRowBytes)
  150.            return(BAD_FORM);
  151.             movmem(buf, *pDest, srcRowBytes);
  152.             buf    += srcRowBytes;
  153.             *pDest += srcRowBytes;
  154.          }
  155.          else
  156.          /* Decompress row to destination plane.*/
  157.             if ( UnPackRow(&buf, pDest, nFilled,  srcRowBytes) )
  158.                     /*  pSource, pDest, srcBytes, dstBytes  */
  159.                return(BAD_FORM);
  160.  
  161.       }   /* End of inner "for" */
  162.    }      /* End of outer "for" */
  163.  
  164.    return(IFF_OKAY);
  165. }
  166.